Skip to main content

leetcode中python新用法

leetcode中python新用法

2020-07-24

  • dict setdefault
In [45]: a = dict()

In [46]: a.setdefault?
Docstring: D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
Type: builtin_function_or_method

In [47]: a.setdefault("t", 2)
Out[47]: 2

In [48]: a
Out[48]: {'t': 2}

以前写法

if c not in node:
node[c] = dict()
node = node[c]

新写法

node = node.setdefault(c, dict())
  • 列表区间修改
In [49]: a = [1, 2, 3, 4]

In [50]: b = [33, 44]

In [51]: a[1:2] = b

In [52]: a
Out[52]: [1, 33, 44, 3, 4]
  • 列表浅复制问题
In [39]: a = [1, 2, 3]

In [40]: b = []

In [41]: b.append(a)

In [42]: b
Out[42]: [[1, 2, 3]]

In [43]: a.clear()

In [44]: b
Out[44]: [[]]

  • backtrack回溯递归对内存引用理解不深刻的bug

遇到一个对内存引用理解不深刻的bug,本来以为已经很熟悉了。

在回溯算法中,列表如果要重复使用,就不能进行引用修改,只能对数组本身进行inplace的修改。 比如seq = seq[:-i]就不能出现,而应该是for _ in range(i): seq:pop().

for i in reversed(range(0, counts + 1)):  # 不使用也算上
seq.extend([arr[start]] * i)
combo(arr, start + 1, end, target - arr[start] * i, seq, rv)
# wtf, 又是一个傻逼bug,在引用的时候修改引用本身; 要么就每次调用前复制一遍
# seq = seq[: -i]
for _ in range(i):
seq.pop()
  • 列表 slice 复制

列表分组slice后,新列表元素的内存编码还是同一个,但在修改的时候并不会被牵连,内存编码也随着换了。看来是先引用,遇到修改的时候在复制一波的算法, copy on change.


In [5]: a
Out[5]: ['a', 'b', 'c']

In [6]: b
Out[6]: ['t']

In [7]: id(b)
Out[7]: 4561666248

In [8]: id(a)
Out[8]: 4561586888

In [9]: for i in a:
...: print(id(i))
...:
4531716312
4531016848
4530807896

In [10]: t = a[1:3]

In [11]: for i in t:
...: print(id(i))
...:
4531016848
4530807896

In [12]: t
Out[12]: ['b', 'c']

In [13]: t[-1] = 666

In [14]: t
Out[14]: ['b', 666]

In [15]: a
Out[15]: ['a', 'b', 'c']

In [16]: for i in t:
...: print(id(i))
...:
4531016848
4561319632

go的slice看来并没有copy on change的操作

package main

import "fmt"

func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}

var s []int = primes[1:4]
s[0] = 777
fmt.Println(primes)
fmt.Println(s)
}

[2 777 5 7 11 13]
[777 5 7]

python slice的copy on modified

In [17]: a = list('abcd')

In [18]: b = a[1:3]

In [19]: b[0] = 777

In [20]: a
Out[20]: ['a', 'b', 'c', 'd']

In [21]: b
Out[21]: [777, 'c']
  • split用空白拆分的区别

使用split()不带参数,可以把所有空格划分的拆开,如果使用一个空白字符串作为参数,则遇到连续的空白会被拆分为多个元素。


In [5]: s.split?
Docstring:
S.split(sep=None, maxsplit=-1) -> list of strings

Return a list of the words in S, using sep as the
delimiter string. If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are
removed from the result.
Type: builtin_function_or_method

In [6]: '1 2 3'.split()
Out[6]: ['1', '2', '3']

In [7]: '1 2 3'.split(' ')
Out[7]: ['1', '', '', '2', '3']